package com.example.musictutor.services;

import java.util.List;

import com.example.musictutor.domain.Song;
import com.example.musictutor.domain.SongNote;

public class MatchSongs {
	
	/**
	 * Compares to song by checking 3 possible errors
	 * 	1. Amount of notes
	 * 	2. Difference in notes
	 * 	3. Difference in note lenghts
	 * 
	 * @param song Song1 that are to be compared. The order of the parameters and songs does not matter.
	 * @param comparedsong Song2 that are to be compared. The order of the parameters and songs does not matter.
	 * 
	 * @return 0 is successful.
	 * @return 1 is failed. Amount of notes difference.
	 * @return 2 is failed. Notes differ.
	 * @return 3 is failed. Position difference.
	 * @return 4 is song1 or song2 is null.
	 */		
	public int compareSongs(Song song, Song comparedsong) {
		
		if(song == null ||comparedsong == null)
			return 4;
		
		List<SongNote> songNotes = song.getNotes();
		List<SongNote> comparedSongNotes = comparedsong.getNotes();
		
		if(songNotes.size() != comparedSongNotes.size())
			return 1;
		
		SongNote songNote = null;
		SongNote comparedNote = null;
		SongNote tempNote = null;
		int currentNotePosition = 0;
		int nextNotePosition = 0;
		int currentNoteDuration = 0;
		double variant = 0;
		
		for(int i=0;i<songNotes.size();i++) {
			songNote = songNotes.get(i);
			comparedNote = comparedSongNotes.get(i);
			
			if(i < songNotes.size()-1) {
				currentNotePosition = comparedNote.getStartPosition();
				nextNotePosition = comparedSongNotes.get(i+1).getStartPosition();
				currentNoteDuration = 999;	//comparedNote.getEndPosition() - currentNotePosition;
				
				variant = getVariant(song.getTempo(), currentNoteDuration);
				
				if(nextNotePosition < currentNotePosition + variant && nextNotePosition > currentNotePosition - variant) {
					if(songNote.getName().equals(comparedNote.getName()))
						continue;
					else {
						tempNote = comparedNote;
						comparedSongNotes.set(i, comparedSongNotes.get(i+1));
						comparedSongNotes.set(i+1, tempNote);
						comparedNote = comparedSongNotes.get(i);
					}
				}
			}
			
			if(!songNote.getName().equals(comparedNote.getName()))
				return 2;
		}
		
		int index = 0;
		while(index < songNotes.size()) {
			// check start position
			if(!checkPosition(songNotes.get(index), comparedSongNotes.get(index), song.getTempo()))
				return 3;
			
			index++;
		}
		
		return 0;
	}
	

	private boolean checkPosition(SongNote note1, SongNote note2, int tempo) {
		int note1Duration = 999;	//note1.getEndPosition() - note1.getStartPosition();
		
		double variant = getVariant(tempo, note1Duration);
		
		int note2Start = note2.getStartPosition();
		int note2End = note2.getEndPosition();
		int note1Start = note1.getStartPosition();
		int note1End = note1.getEndPosition();
		
		if(note2Start > note1Start + variant || note2Start < note1Start - variant) 
			return false;
		
		if(note2End > note1End + variant || note2End < note1End - variant) 
			return false;
		
		return true;
		
		
	}
	
	private double getVariant(int tempo, int noteDuration) {
		int beatDuration = getBeatDuration(tempo);
		double noteBeats = ((double)noteDuration) / beatDuration; 
		return (noteBeats * beatDuration) / 4;
	}
	
	private int getBeatDuration(int tempo) {
		float bps = tempo / 60;
		float miliPerBeat = (1 / bps) * 1000;
		
		return (int) miliPerBeat;
	}
}






























